package gitobject;



import sha1.SHA1;

import zlib.ZLibUtils;
import fileoperation.FileReader;

import java.io.*;
import java.lang.reflect.Array;
import java.security.MessageDigest;
import java.util.*;


public class Tree extends GitObject implements Serializable{
    protected ArrayList<GitObject> treeList;	//GitObjects in tree

    public ArrayList<GitObject> getTreeList(){
        return treeList;
    }

    public Tree(){}

    /**
     * Constructor
     * @param file
     * @throws Exception
     */
    public Tree(File file) throws Exception {
        this.treeList = new ArrayList<>();
        this.fmt = "tree";
        this.mode = "040000";
        this.value = "";
        this.file = file;
        this.key = genKey(file);
        this.writeObject();
    }

    /**
     * Deserialize a tree object with treeId and its path.
     * @param Id
     * @param Id
     * @throws IOException
     */
    public static Tree deserialize(String filePath) throws IOException {
        try{
            File fileT = new File(filePath);
            ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileT));
            Tree t = (Tree) in.readObject();
            return t;
        }catch (Exception e){
            e.printStackTrace();
        }
        /* Todo: You should delete the return statement before you start. */
        return new Tree();
    }


    /**
     * Sort the files in a certain order. You should consider whether it's a file or a directory.
     * @param fs
     * @return List
     */
    public List sortFile(File[] fs){
        List fileList = Arrays.asList(fs);
        Collections.sort(fileList, new Comparator<File>() {
            @Override //表示重写方法
            public int compare(File o1, File o2) {
                /* Todo: Add your code here. */
                if (o1.isDirectory() && o2.isFile())
                    return 1;
                if (o1.isFile() && o2.isDirectory())
                    return -1;
                return o1.compareTo(o2);
            }
        });
        return fileList;
    }

    /**
     * Generate the key of a tree object.
     * @param dir
     * @return String
     * @throws Exception
     */
    public String genKey(File dir) throws Exception{
//        /* Todo: Add your code here. */
//        key = SHA1.getHash(dir);//NOT SURE
//        return key;
        File[] fs = dir.listFiles();
        List fileList = sortFile(fs);

        for(int i = 0; i < fs.length; i++){
            if(fs[i].isDirectory()){
                Tree tree = new Tree(fs[i]);
                treeList.add(tree);
                tree.compressWrite();
                value += "040000 tree " + tree.getKey() + "\u0020" + fs[i].getName() + "\n";
            }
            else if(fs[i].isFile()){
                Blob blob = new Blob(fs[i]);
                treeList.add(blob);
                blob.compressWrite();
                value += "100644 blob " + blob.getKey() + "\u0020" + fs[i].getName() + "\n";
            }
        }
        key = SHA1.getHash(value);
        return key;
    }

    @Override
    public String toString(){
        return "040000 tree " + key;
    }

}
